package design.pattern.Lu21InterpreterPattern;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Map;
import java.util.Stack;

/**
 * @program JavaBase
 * @description: 解释器模式
 * @author: zhanglu
 * @create: 2020-05-19 17:30:00
 */
public class InterpreterPattern01 {

    public static void main(String[] args) throws IOException {
        String expStr = getExpStr();
        //赋值
        Map<String, Integer> map = getValue(expStr);
        Calculator calculator = new Calculator(expStr);
        System.out.println("运算结果为：" + expStr + "=" + calculator.run(map));
    }

    public static String getExpStr() throws IOException {
        System.out.println("请输入表达式：");
        return (new BufferedReader(new InputStreamReader(System.in))).readLine();
    }

    public static Map<String, Integer> getValue(String expStr) throws IOException {
        Map<String, Integer> map = new HashMap<>();
        for (char ch : expStr.toCharArray()) {
            if(ch != '+' && ch != '-'){
                //解决重复参数问题
                if(!map.containsKey(String.valueOf(ch))){
                    System.out.println("请输入"+ch+"的值：");
                    String in = (new BufferedReader(new InputStreamReader(System.in))).readLine();
                    map.put(String.valueOf(ch), Integer.valueOf(in));
                }
            }
        }
        return map;
    }

}

abstract class Expression{
    //key：公式中的参数 value：具体值
    abstract int interpreter(Map<String, Integer> map);
}

//变量解析器
class VarExpression extends Expression{

    private String key;

    public VarExpression(String key){
        this.key = key;
    }

    @Override
    int interpreter(Map<String, Integer> map) {
        return map.get(this.key);
    }
}
//抽象运算富豪解析器
abstract class SymbolExpression extends Expression{
    protected Expression left;
    protected Expression right;

    public SymbolExpression(Expression left, Expression right){
        this.left = left;
        this.right = right;
    }
}
//加法解析器
class AddExpression extends SymbolExpression{
    public AddExpression(Expression left, Expression right){
        super(left, right);
    }
    @Override
    public int interpreter(Map<String, Integer> map) {
        return super.left.interpreter(map) + super.right.interpreter(map);
    }
}
//减法解析器
class SubExpression extends SymbolExpression{

    public SubExpression(Expression left, Expression right){
        super(left, right);
    }

    @Override
    public int interpreter(Map<String, Integer> map) {
        return super.left.interpreter(map) - super.right.interpreter(map);
    }
}

class Calculator{
    private Expression expression;
    public Calculator(String expStr){
        Stack<Expression> stack = new Stack<>();
        char[] chars = expStr.toCharArray();
        Expression left = null;
        Expression right = null;
        for (int i = 0; i < chars.length; i++) {
            if(chars[i] == '+'){
                left = stack.pop();
                right = new VarExpression(String.valueOf(chars[++i]));
                stack.push(new AddExpression(left, right));
            }else if(chars[i] == '-'){
                left = stack.pop();
                right = new VarExpression(String.valueOf(chars[++i]));
                stack.push(new SubExpression(left, right));
            }else{
                stack.push(new VarExpression(String.valueOf(chars[i])));
            }
        }
        //把运算结果抛出来
        this.expression = stack.pop();
    }

    public int run(Map<String, Integer> map){
        return this.expression.interpreter(map);
    }

}







